package UI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.BevelBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;

import data_management.InvDBManager;
import data_management.Main;
import data_management.PermissionManager;


/**
 * This class is responsible for making sales.
 * @author gldunn
 *
 */
public class SaleInterface extends JPanel implements IPrint, ActionListener, DocumentListener  {
	
	public static final SaleInterface saleInterface = new SaleInterface();
	//@ invariant saleInterface != null;
	
	public JTextField searchField;
	//@ invariant searchField != null;
	public JComboBox columnFilter;
	//@ invariant columnFilter != null;

	private InvDBManager invDB;
	//@ invariant invDB != null;

	public ScrollTable search;
	//@ invariant search != null;
	public ScrollTable sale;
	//@ invariant sale != null;
	
	public JButton toSale;
	//@ invariant toSale != null;
	public JButton toInv;
	//@ invariant toInv != null;
	public JButton checkout;
	//@ invariant checkout != null;
	public JButton clearSale;
	//@ invariant clearSale != null;
	
	public JTextField subtotal;
	//@ invariant subtotal != null;
	public JTextField tax;
	//@ invariant tax != null;
	public JTextField total;
	//@ invariant total != null;
	public JTextField tendered;
	//@ invariant tendered != null;
	public JTextField change;
	//@ invariant change != null;
	
	/**
	 * This method does nothing, call initialize to activate the object
	 */
	public SaleInterface() {
		
	}

	/** 
	 * This method initializes a sale interface object.
	 */
	/*@
	 @ assignable searchField;
	 @ assignable columnFilter;
	 @ assignable invDB;
	 @ assignable search;
	 @ assignable sale;
	 @ assignable toSale;
	 @ assignable toInv;
	 @ assignable checkout;
	 @ assignable clearSale;
	 @ assignable subtotal;
	 @ assignable tax;
	 @ assignable total;
	 @ assignable tendered;
	 @ assignable change;
	 @ 
	 @*/
	public void initialize() {
		
		// Connect to the inventory database
		invDB = InvDBManager.getInstance();
//		logDB = LogDBManager.getInstance();
		
		// Set up the panel
		this.setBackground(Color.blue);
		this.setPreferredSize(new Dimension(Main.DEFAULT_WIDTH, Main.DEFAULT_HEIGHT));
		this.setLayout(new BorderLayout());
		
		// Make the data containers for the tables
		Vector<String> columns = invDB.getColumns("inventory");
		search = new ScrollTable(columns);
		
		// Remove the "Quantity" column from the sale table
		for(int i = 0; i < columns.size(); i++) {

			if(columns.get(i).equalsIgnoreCase(InvDBManager.QUANTITY)) {
				columns.remove(i);
				i--;
			}
		}
		sale = new ScrollTable(columns);
		
		// Add all inventory to the search window
		ResultSet rs = invDB.searchDatabase("%", InvDBManager.NAME);
		search.updateTable(rs);
		
		// The main panel for the tables
		JPanel tablePanel = new JPanel();
		tablePanel.setLayout(new BoxLayout(tablePanel, BoxLayout.X_AXIS));
		
		// make a panel for the buttons
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
				
		// Add the buttons that go from and to the sale
		toSale = new JButton("<- Add");
		toInv = new JButton("Remove ->");
		clearSale = new JButton("Clear Sale");
		buttonPanel.add(toSale);
		buttonPanel.add(toInv);
		buttonPanel.add(clearSale);
		
		// The search table box
		JPanel searchPanel = new JPanel();
		searchPanel.setLayout(new BorderLayout());
		
		// The search bar creation and setup
		JPanel searchBar = new JPanel();
		searchBar.setLayout(new BoxLayout(searchBar, BoxLayout.X_AXIS));
//		searchBar.setPreferredSize(searchPanel.getSize());
		
		// The search field
		searchField = new JTextField(15);
		searchField.setMaximumSize(new Dimension(50, 25));
		searchField.setMinimumSize(new Dimension(50, 25));
		searchField.getDocument().addDocumentListener(this);
		
		// Add the filter label
		JLabel filterLabel = new JLabel("Filter by: ");
		searchBar.add(filterLabel);
		
		// Add our filter by drop down box
		columns = InvDBManager.getInstance().getColumns("inventory");
		columnFilter = new JComboBox(columns);
		columnFilter.setMaximumSize(new Dimension(50, columnFilter.getMaximumSize().height));
		columnFilter.addActionListener(this);
		
		// the search field, box, and label to the search bar
		searchBar.add(Box.createHorizontalGlue());
		searchBar.add(searchField);
		searchBar.add(filterLabel);
		searchBar.add(columnFilter);
		
		// Add the search bar to the north of the border layout
		searchPanel.add(searchBar, BorderLayout.NORTH);
		searchPanel.add(search.getPane());
		
		
		// Add all the search stuff to the tablePanel
		tablePanel.add(sale.getPane());
		tablePanel.add(buttonPanel);
		tablePanel.add(searchPanel);
		
		// Set a border for the table panel
		tablePanel.setBorder(new BevelBorder(1));
		
		// Create a display set for sale stuff
		JPanel totalsPanel = new JPanel();
		totalsPanel.setLayout(new BoxLayout(totalsPanel, BoxLayout.X_AXIS));
		
		// The JLabels and matching text fields
		
		// Subtotal
		JPanel tmpPanel = new JPanel();
		tmpPanel.setLayout(new BoxLayout(tmpPanel, BoxLayout.X_AXIS)); 
		subtotal = new JTextField("0");
		subtotal.setEditable(false);
		subtotal.setMaximumSize(new Dimension(50,25));
		subtotal.setAlignmentX(Component.LEFT_ALIGNMENT);
		tmpPanel.add(new JLabel("  Subtotal: "));
		tmpPanel.add(subtotal);
		totalsPanel.add(tmpPanel);
		
		// Tax
		tmpPanel = new JPanel();
		tmpPanel.setLayout(new BoxLayout(tmpPanel, BoxLayout.X_AXIS)); 
		tax = new JTextField("0");
		tax.setEditable(false);
		tax.setMaximumSize(new Dimension(50,25));
		tax.setAlignmentX(Component.LEFT_ALIGNMENT);
		tmpPanel.add(new JLabel("  Tax: "));
		tmpPanel.add(tax);
		totalsPanel.add(tmpPanel);

		// Total
		tmpPanel = new JPanel();
		tmpPanel.setLayout(new BoxLayout(tmpPanel, BoxLayout.X_AXIS)); 
		total = new JTextField("0");
		total.setEditable(false);
		total.setMaximumSize(new Dimension(50,25));
		total.setAlignmentX(Component.LEFT_ALIGNMENT);
		tmpPanel.add(new JLabel("  Total: "));
		tmpPanel.add(total);
		totalsPanel.add(tmpPanel);

		// Amount Tendered
		tmpPanel = new JPanel();
		tmpPanel.setLayout(new BoxLayout(tmpPanel, BoxLayout.X_AXIS)); 
		tendered = new JTextField("0");
		tendered.setMaximumSize(new Dimension(50,25));
		tendered.setAlignmentX(Component.LEFT_ALIGNMENT);
		tendered.getDocument().addDocumentListener(this);
		tmpPanel.add(new JLabel("  Amount Tendered: "));
		tmpPanel.add(tendered);
		totalsPanel.add(tmpPanel);
		
		// Change
		tmpPanel = new JPanel();
		tmpPanel.setLayout(new BoxLayout(tmpPanel, BoxLayout.X_AXIS)); 
		change = new JTextField("0");
		change.setMaximumSize(new Dimension(50,25));
		change.setAlignmentX(Component.LEFT_ALIGNMENT);
		change.setEditable(false);
		tmpPanel.add(new JLabel("  Change: "));
		tmpPanel.add(change);
		totalsPanel.add(tmpPanel);
		
		// Checkout Button
		checkout = new JButton("Checkout");
		totalsPanel.add(checkout);
		

		// Add the tables to the main window
		this.add(tablePanel, BorderLayout.CENTER);
		this.add(totalsPanel, BorderLayout.SOUTH);
		
		toSale.addActionListener(this);
		toInv.addActionListener(this);
		clearSale.addActionListener(this);
		checkout.addActionListener(this);
	}
	
	/** This method recalculates the contents of the displayed GUI boxes to match the current sale object. */
	/*@
 	 @ requires sale != null;
 	 @ assignable change;
 	 @ assignable total;
 	 @ assignable subtotal;
 	 @ assignable tax;
	 @ ensures Double.valueOf(change.getString()) = Double.valueOf(tendered.getString()) - Double.valueOf(total.getString());
	 */
	public void retotal() {
		
		// The number of rows
		int rows = sale.getModel().getRowCount();
		
		// Find the price column
		int i = 0;
		for(; i < sale.getModel().getColumnCount(); i++) {
			String tmp = sale.getModel().getColumnName(i);
			if(tmp.equals(InvDBManager.PRICE))	{
				break;
			}
		}
		
		// Sum the total value
		double total_value = 0;
		
		for(int j = 0; j < rows; j++) {
			total_value += Double.valueOf((String) sale.getModel().getValueAt(j, i));
		}
		
		subtotal.setText(String.format("%.2f", total_value));
		tax.setText(String.format("%.2f", total_value*0.06));
		total.setText(String.format("%.2f", total_value*1.06));

		try {
			change.setText(String.format("%.2f", Double.valueOf(tendered.getText()) - Double.valueOf(total.getText())));
		}
		catch(Exception e) {
			//e.printStackTrace();
		}

	}
	
	@Override
	public void Print() {
		// TODO Auto-generated method stub
		
	}
	
	
	public static SaleInterface getInstance() {
		
		return saleInterface;
	}

	/** This method searches the database for all entries which begin with the search text box contents, and makes it so the table contains the results. */
	/*@
	 @ 
	 @ assignable search;
	 @
	 */
	private void performSearch() {
		String key = searchField.getText() + "%";
		String column = columnFilter.getSelectedItem().toString();
		ResultSet results = InvDBManager.getInstance().searchDatabase(key, column);
		search.updateTable(results);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if(e.getSource() == toSale) {
			if (search.getTable().getSelectedRow() != -1) {
				sale.copyFrom(search);
				retotal();
			}
		}
		else if(e.getSource() == toInv) {
			sale.removeSelected();
			retotal();
		}
		else if(e.getSource() == columnFilter) {
			performSearch();
		}
		else if(e.getSource() == clearSale) {
			sale.clear();
			retotal();
		}
		else if(e.getSource() == checkout) {
			int retval = JOptionPane.showOptionDialog(this, "Is this the final sale? \n Price: " + total.getText() + "\n Amount Tendered: " + tendered.getText() + "\n Change: " + change.getText(), "Sale Confirmation", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);

			if(retval == JOptionPane.YES_OPTION) {
				// Do stuff
				System.out.println("Sale Confirmed");
				// Update inventory
				// The item number column

				int col = sale.getModel().findColumn(InvDBManager.ITEM_NUM);

				for(int i = 0; i < sale.getModel().getRowCount(); i++) {
					invDB.decrementItem((String) sale.getModel().getValueAt(i, col), PermissionManager.getInstance().desktopUser);
				}
				// Update logs
				
				sale.clear();
				performSearch();
				retotal();
			}
		}
	}



	@Override
	public void changedUpdate(DocumentEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void insertUpdate(DocumentEvent e) {
		// TODO Auto-generated method stub
		if (e.getDocument() == searchField.getDocument()) performSearch();		
		else if(e.getDocument() == tendered.getDocument()) retotal();
	}
	
	@Override
	public void removeUpdate(DocumentEvent e) {
		// TODO Auto-generated method stub
		if (e.getDocument() == searchField.getDocument()) performSearch();		
		else if(e.getDocument() == tendered.getDocument()) retotal();
	}
	
	
	
}
